package com.ke.rule.base;

import java.util.ArrayList;
import java.util.List;

/**
 * 方法的步骤类型
 * 
 * @author guyu
 */
public enum MethodStepType {
  Preprocess            (FuncUnitType.P_D, true),
  ValidateParameter     (FuncUnitType.V),
  DetermineFeasibility  (FuncUnitType.V),
  HandleBusinessLogic   (FuncUnitType.P_D, true),
  DataPersistence       (FuncUnitType.P_D),
  ExecutePostProcessing (FuncUnitType.V_P_D),
  PerformActionOnExit   (FuncUnitType.D, false, true);
  
  // invokable FuncUnitType marker
  private final int typeMarker;

  // reset merged flag before FuncUnit execution, default: false
  private final boolean resetMerged;

  // invoke all FuncUnits even if one or more exception occurs, default: false
  private final boolean invokeAll;
  
  private final int value;

  private MethodStepType(int typeMarker) {
    this(typeMarker, false);
  }
  
  private MethodStepType(int typeMarker, boolean resetMerged) {
    this(typeMarker, resetMerged, false);
  }
  
  private MethodStepType(int typeMarker, boolean resetMerged, boolean invokeAll) {
    this.typeMarker = typeMarker;
    this.resetMerged = resetMerged;
    this.invokeAll = invokeAll;
    this.value = 1 << (1 + ordinal());
  }
  
  public int getValue() {
    return value;
  }

  public boolean isInvokable(FuncUnitType funcUnitType) {
    return (typeMarker & funcUnitType.value) != 0;
  }
  
  public boolean isResetMerged() {
    return resetMerged;
  }
  
  public boolean isInvokeAll() {
    return invokeAll;
  }

  /**
   * 获取路线经过的步骤点
   * @param route
   * @return
   */
  public static List<MethodStepType> map(final int route) {
    List<MethodStepType> steps = new ArrayList<>();
    for (MethodStepType mst : MethodStepType.values()) {
      if (0 == (mst.value & route)) {
        continue;
      }
      steps.add(mst);
    }
    return steps;
  }
}
